home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / lib / tex / inputs / catmac-doc.tex < prev    next >
Encoding:
Text File  |  1991-05-21  |  18.0 KB  |  537 lines

  1. %Please reply to inhb@mcgillb.bitnet.
  2. %For this semester only, to barr@linc.cis.upenn.edu.
  3. %Michael Barr
  4. %Math Dept
  5. %McGill Univ.
  6. %805 Sherbrooke St W
  7. %Montreal, QC
  8. %Canada H3P 1S4
  9. \documentstyle[12pt,catmac]{article}
  10. \textheight=9in \topmargin=0pt\headheight=0pt\headsep=0pt
  11. \textwidth=6.5in \oddsidemargin=0pt
  12. \begin{document}
  13. {\catcode`\ =13\global\let =\ \catcode`\^^M=13
  14. \gdef^^M{\par\noindent}}
  15. \def\verbatim{\tt
  16. \catcode`\^^M=13
  17. \catcode`\ =13
  18. \catcode`\\=12
  19. \catcode`\{=12
  20. \catcode`\}=12
  21. \catcode`\_=12
  22. \catcode`\^=12
  23. \catcode`\&=12
  24. \catcode`\~=12
  25. \catcode`\#=12
  26. \catcode`\%=12
  27. \catcode`\$=12
  28. \catcode`|=0
  29. }
  30.  
  31. All commercial rights reserved.  May be freely distributed
  32. and used with the following exceptions:\\
  33. 1. No commercial use without explicit permission.\\
  34. 2. It may not be used by any employee of a telephone company.\\
  35. 3. It may not be distributed without this notice.
  36.  
  37. \def\\{{\tt \char 92}}
  38.  
  39. \section*{The catmac macros}
  40. The file catmac includes a number of macros for drawing commutative
  41. diagrams in special shapes as well as more flexible macros to paste
  42. together more complicated diagrams.
  43.  
  44. In general, there are two kinds of macros.  The first kind has the
  45. following form
  46. {\tt \\shapename[shape\_parameters]} and is intended to be used in the
  47. following way:
  48. {\verbatim
  49. \begin{center}
  50. \resetparms
  51. \shapename[shape_parameters]
  52. \end{center}
  53. |egroup
  54.  
  55. This will create a shape with the given parameters.  It operates by
  56. building its own picture environment.
  57.  
  58. The second kind of procedure must be used inside a picture environment
  59. and allows the user to put a diagram of a given size and shape at a
  60. given place.  The usual way in which this is used is:
  61.  
  62. {\verbatim
  63. \begin{center}
  64. %code to be explained later
  65. \begin{picture}(xext,yext)
  66. \putshape1(x1,y1)[shape_parameters1]
  67. |dots
  68. \putshape(xn,yn)[shape_parametersn]
  69. \end{picture}
  70. \end{center}
  71. |egroup
  72.  
  73. Here is an example of the first kind of macro.  I will have to explain a
  74. few details before giving examples of the second.  The code
  75. {\verbatim
  76. \begin{center}
  77. \resetparms
  78. \square[A`B`C`D;f`g`h`k]
  79. \end{center}
  80. |egroup
  81. produces the diagram
  82. \begin{center}
  83. \resetparms
  84. \square[A`B`C`D;f`g`h`k]
  85. \end{center}
  86. and the code
  87. {\verbatim
  88. \begin{center}
  89. \resetparms
  90. \Atriangle[A`B`C;f`g`h]
  91. \end{center}
  92. |egroup
  93. produces the diagram
  94. \begin{center}
  95. \resetparms
  96. \Atriangle[A`B`C;f`g`h]
  97. \end{center}
  98. The reason for the shape name will be explained later.
  99.  
  100. If an arrow label extends especially high or low, the space
  101. automatically expands to match.  For example,
  102. {\verbatim
  103. \begin{center}
  104. \resetparms
  105. \square[A`B`C`D;\sum_{i=1}^{\infty}`g`h`\Psi^A_k]
  106. \end{center}
  107. |egroup
  108. will get the diagram
  109. \begin{center}
  110. \resetparms
  111. \square[A`B`C`D;\sum_{i=1}^{\infty}`g`h`\Psi^A_k]
  112. \end{center}
  113. and so on.
  114.  
  115. Before going on, I will explain about the parameters.  Any shape will
  116. have one or two parameters for height and/or length as well as one
  117. parameter for each arrow in the diagram.  These are in addition to the
  118. parameters used in the actual procedures.  For example, the procedure
  119. {\verbatim
  120. \begin{center}
  121. \setsqparms[-1`0`2`-3;1000`700]
  122. \square[A`B`C`D;f`g`h`k]
  123. \end{center}
  124. |egroup
  125. gives the square:
  126. \begin{center}
  127. \setsqparms[-1`0`2`-3;1000`700]
  128. \square[A`B`C`D;f`g`h`k]
  129. \end{center}
  130. The meaning is as follows.  The first four parameters refer to four
  131. arrows in linguistic order (top, left, right, bottom).  A negative
  132. number gives a backward arrow, while a zero causes it to be omitted.  A
  133. parameter with an absolute value of 1 is ordinary, while 2 gives an
  134. arrow with a tail (monomorphism) and 3 a double headed arrow
  135. (epimorphism).  The last two parameters determine the width and height,
  136. respectively, in units of 0.01 em (an em is the width of an M, the
  137. widest letter in a font).
  138.  
  139. Although {\tt \\resetparms} works with any of the shapes (and simply
  140. chooses
  141. the default values of 1 for all arrows and 500 for height and width),
  142. the remaining shapes use different names.  The various parameter setting
  143. procedures are
  144. {\verbatim
  145. \setsqparms[#1`#2`#3`#4;#5`#6]
  146. \settriparms[#1`#2`#3;#4]
  147. \settripairparms[#1`#2`#3`#4`#5;#6]
  148. \setrecparms[#1`#2]
  149. |egroup
  150. With the exception of the last, the parameters before the semicolon set
  151. the arrow types and the one or two after set lengths.  In the last one,
  152. both parameters are lengths.
  153.  
  154. Here are the shapes.  We have already seen the shape {\tt \\square}.
  155. There are eight different triangles, all isoceles right triangles in
  156. different orientations.  The names all have the form {\tt
  157. \\xtriangle}, where x is the letter that most closely resembles the
  158. actual shape of the triangle.
  159.  
  160. Here are the names, followed by a sample of each one:
  161. \begin{list}{}{}
  162. \item{\tt \\btriangle}\samepage
  163. \begin{center}
  164. \resetparms
  165. \btriangle[A`B`C;f`g`h]
  166. \end{center}
  167. \pagebreak[0]
  168. \item{\tt \\dtriangle}\samepage
  169. \begin{center}
  170. \resetparms
  171. \dtriangle[A`B`C;f`g`h]
  172. \end{center}
  173. \pagebreak[0]
  174. \item{\tt \\ptriangle}\samepage
  175. \begin{center}
  176. \resetparms
  177. \ptriangle[A`B`C;f`g`h]
  178. \end{center}
  179. \pagebreak[0]
  180. \item{\tt \\qtriangle}\samepage
  181. \begin{center}
  182. \resetparms
  183. \qtriangle[A`B`C;f`g`h]
  184. \end{center}
  185. \pagebreak[0]
  186. \item{\tt \\Atriangle}\samepage
  187. \begin{center}
  188. \resetparms
  189. \Atriangle[A`B`C;f`g`h]
  190. \end{center}
  191. \pagebreak[0]
  192. \item{\tt \\Vtriangle}\samepage
  193. \begin{center}
  194. \resetparms
  195. \Vtriangle[A`B`C;f`g`h]
  196. \end{center}
  197. \pagebreak[0]
  198. \item{\tt \\Ctriangle}\samepage
  199. \begin{center}
  200. \resetparms
  201. \Ctriangle[A`B`C;f`g`h]
  202. \end{center}
  203. \pagebreak[0]
  204. \item{\tt \\Dtriangle}\samepage
  205. \begin{center}
  206. \resetparms
  207. \Dtriangle[A`B`C;f`g`h]
  208. \end{center}
  209. \end{list}
  210.  
  211. In addition, there are two special diagrams that come up often enough to
  212. be worth having a special macros for.
  213. \begin{list}{}{}
  214. \item{\tt \\Atrianglepair}\samepage
  215. \begin{center}
  216. \resetparms
  217. \Atrianglepair[A`B`C`D;f`g`h`k`l]
  218. \end{center}
  219. \item{\tt \\Vtrianglepair}\samepage
  220. \begin{center}
  221. \resetparms
  222. \Vtrianglepair[A`B`C`D;f`g`h`k`l]
  223. \end{center}
  224. \end{list}
  225. Finally, there is one special shape that is probably not used by very
  226. many mathematicians.  Still I have it and the user might as well share
  227. it.
  228.  
  229. {\verbatim
  230. \recurse[A`B`R`C;s`f_0`f`t_0`t]
  231. |egroup
  232. \begin{center}
  233. \resetparms
  234. \recurse[A`B`R`C;s`f_0`f`t_0`t]
  235. \end{center}
  236.  
  237. Notice what happens if the first parameter is empty:
  238. {\verbatim
  239. \recurse[`B`R`C;s`f_0`f`t_0`t]
  240. |egroup
  241. \begin{center}
  242. \resetparms
  243. \recurse[`B`R`C;s`f_0`f`t_0`t]
  244. \end{center}
  245.  
  246. This takes care of the simple procedures.  The remaining procedures are
  247. there as building blocks for more complicated diagrams.
  248.  
  249. These take the form
  250. \vskip0pt\noindent
  251. {\tt \\putshape(xpos,ypos)[shape\_parameters]}
  252. \vskip0pt\noindent
  253. where
  254. shape is one of the 11 shapes (excluding {\tt \\recurse}) described
  255. above
  256. and the parms are as described there.  The parameters {\tt  xpos} and
  257. {\tt  ypos} are the offsets from the lower left corner of the picture
  258. measured in umits of .01 em in the usual \LaTeX\ fashion.
  259.  
  260. There is one
  261. more shape which is simply an arrow with an attached label.  This is
  262. called {\tt \\putmorphism} and it is used with the syntax
  263. \vskip0pt\noindent
  264. {\tt
  265. \\putmorphism(xpos,ypos)(run,rise)[node1`node2`label]\{dist\}\{type\}\{loc\}}
  266. \vskip0pt\noindent
  267. Here the parameters {\tt  xpos} and
  268. {\tt  ypos} are as above.  The slope is {\tt rise/run} where {\tt rise}
  269. and {\tt run} are two numbers that give the slope in accordance with the
  270. \LaTeX\ rules.  That is rise and run must have no common divisor and
  271. must not exceed 4 in absolute value.  In addition, these procedures are
  272. defined so that rise must not be positive and if it is zero, then run
  273. must be positive.  In other words, all arrows must go in the linguistic
  274. direction, downwards or to the right.  Arrows can be made to go in the
  275. reverse direction as explained below.
  276.  
  277. The next three parameters are the node that appears first (in linguistic
  278. order), the one that appears second and the arrow label.  The next
  279. paramater is the distance in the sense of \LaTeX\ between the centers of
  280. the nodes.  This means it is the horizontal component of the distance,
  281. unless that is negative, in which case it is the vertical distance.  The
  282. second parameter is the code for the arrowtype, an integer between -3
  283. and 3 with the same meaning as explained above.  Using negative values
  284. of this parameter allows one to draw an arrow that goes upwards or left.
  285. Note, however, that node1 is always the node that is above or to the
  286. left of node2.  The last parameter should have the value a,b,l,r or m.
  287. The values a and b are used only for horizontal arrows and direct the
  288. arrow label to be placed above or below the arrow.  The values l and r
  289. are used for all other arrows and direct the label to be left or right
  290. of the arrow.  Finally, a vertical arrow only can be given the parameter
  291. m, in which case the arrow will be gapped and the label placed in the
  292. middle of the gap.
  293.  
  294. In general, the simple macros are designed to be used as indicated
  295. either in the {\tt \\begin\{center\} \ldots \\end\{center\}} environment
  296. or in one of the others, usually
  297. {\verbatim
  298. \begin{equation}\begin{array}{c}
  299. |dots
  300. \end{array}\end{equation}|egroup
  301.  
  302. The \\putshape macros must be used inside a picture environment that is
  303. normally placed inside a centering or similar environment.  The
  304. reference point for the positioning parameters is determined as the
  305. lower left corner of the smallest rectangle with sides parallel to the
  306. coordinate axes that includes the center points of all nodes on its
  307. border.  This rectangle will be degenerate in the case of a horizontal
  308. or vertical morphism.  The reference point may either be on or outside
  309. the actual figure.  For example, in the case of the btriangle, it is the
  310. center of the lower left node, while for a qtriangle it is outside the
  311. triangle itself being the fourth corner of the enclosing square.
  312.  
  313. The macros are made so that they fit together well.  That is why all
  314. distances are from node centers to node centers.  If a vertex is part of
  315. two shapes, it is probably best not to repeat it, since it is
  316. conceivable that round-off errors will cause its two appearances to be
  317. slightly offset.  It can either be omitted or, since the width is used
  318. to determine the amount to shorten horizontal arrows, replaced by {\tt
  319. \\phantom} versions.  Both methods are illustrated in the example given
  320. at the end.
  321.  
  322. One more thing has to be described.  when beginning picture mode, you
  323. have to allocate both a horizontal and vertical space.  the vertical
  324. space is crucial and, while the horizontal is not as critical, it still
  325. determines whether the figure is properly centered.  This partially
  326. automated as follows.  You begin by giving values to two variables,
  327. called {\tt \\xext} and {\tt\\yext} (for x-extent and y-extent, resp.).
  328. This is done by the declarations
  329. {\tt\\xext=xparm, \\yext=yparm}, where {\tt xparm} and {\tt yparm} are
  330. the sum of all the horizontal and vertical distances used in the
  331. procedures.  Of course, if two shapes are put side by side, the
  332. x-extents will be the sum plus the space between them if any, while the
  333. y-extent will be that of the larger one.  In figuring out these extents,
  334. ignore the heights and widths of the vertices and arrow labels.  So what
  335. these really measure is the distance between the two most distantly
  336. separated arrows in the diagram, or rather it would if none was omitted.
  337.  
  338. These must be adjusted for the space occupied by the labels and nodes.
  339. There are procedures to do this automatically, but they require an
  340. assist from the user.  First, there are six raw procedures that can
  341. carry out these adjustments.  They are {\verbatim \topadjust,
  342. \botadjust, \leftadjust, \rightadjust, \leftsladjust, \rightsladjust
  343. |egroup that take 3 parameters each and adjust {\tt\\xext} and
  344. {\tt\\yext} for the heights and widths of the nodes.  They all take as
  345. parameters two nodes and one arrow and figure out which one stands the
  346. highest or sticks out the furthest and makes the appropriate adjustment.
  347. The first four can be given the nodes in either order and the arrow
  348. label comes third.  In the case of the last two, making adjustment for
  349. slnat arrows of a triangle, the first parameter is the node that sticks
  350. out the further, the second is the other node (which is the rarely the
  351. determining one) and the third is the label.  If it is clear that a node
  352. or label cannot possibly be the salient one, then it may safely be
  353. omitted.
  354.  
  355. In practice, it is hardly ever necessary to use these procedures.  There
  356. is a single procedure called {\tt\\adjust} that is used as follows:
  357. {\verbatim
  358. \adjust[tnode`tlabel;lnode`llabel;rnode`rlabel;bnode`blabel]
  359. |egroup
  360. It is usually necessary to specify only four parameters leaving the
  361. remainder blank.  For example, if the top label is empty, then some node
  362. (if there is more than one, always use the tallest; if in doubt use them
  363. both concatenated).  If the label is not blank, it will almost stick up
  364. further than the node.  If in doubt, give them both, but this should
  365. rarely happen.  Similar remarks apply to the other pairs of parameters.
  366.  
  367. These adjustment procedures adjust not only {\tt\\xext} and {\tt\\yext}
  368. but another pair of variables called {\tt\\xpos} and {\tt\\ypos}.  When
  369. this has all been done, you can now begin picture mode with
  370. {\verbatim
  371. \begin{picture}(\xext,\yext)(\xoff,\yoff)
  372. |dots
  373. \end{picture}
  374. |egroup
  375.  
  376. A somewhat baroque (but taken from an actual text) example illustrates
  377. most of these points.
  378. {\verbatim
  379. \begin{center}
  380. \xext=2100 \yext=2100
  381. \adjust[`\mu;`T\eta'T;`\sigma;`T'T\eta']
  382. \begin{picture}(\xext,\yext)(\xoff,\yoff)
  383. \putmorphism(0,2100)(0,-1)[``T\eta'T]{1400}1l
  384. \putmorphism(0,2100)(1,0)[TT`T`\mu]{700}1a
  385. \putmorphism(0,2100)(1,-1)[`TTT'`TT\eta']{700}1l
  386. \putmorphism(700,2100)(1,-1)[`TT'`T\eta]{700}1r
  387. \put(700,1750){\makebox(0,0){1}}
  388. \putmorphism(700,1420)(1,0)[\phantom{TTT'}`\phantom{TT'}`\mu
  389.   T']{700}1a
  390. \putmorphism(700,1380)(1,0)[\phantom{TTT'}`%
  391.   \phantom{TT'}`T\sigma]{700}1b
  392. \setsqparms[0`1`1`1;700`700]
  393. \putsquare(700,700)[TTT'`TT'`TT'TT'`TT'T';`T\eta'TT'``]
  394. \putmorphism(700,700)(1,0)[\phantom{TT'TT'}`%
  395.   \phantom{TT'T'}`TT'\sigma]{700}1a
  396. \put(300,1400){\makebox(0,0){2}}
  397. \put(950,1050){\makebox(0,0){3}}
  398. \settriparms[0`1`0;700]
  399. \putbtriangle(1400,700)[``TT';T\eta'T'`id`]
  400. \putmorphism(1400,700)(1,0)[\phantom{TT'T'}`%
  401.   \phantom{TT'}`T\mu']{700}1a
  402. \put(1600,1050){\makebox(0,0){6}}
  403. \setsqparms[1`1`0`1;700`700]
  404. \putsquare(0,0)[TT'T`\phantom{TT'TT'}`T'T`T'TT';%
  405.   TT'T\eta'`\sigma T``T'T\eta']
  406. \putmorphism(700,0)(1,0)[\phantom{T'TT'}`%
  407.   \phantom{T'T'}`T'\sigma]{700}1b
  408. \setsqparms[0`0`1`1;700`700]
  409. \putsquare(1400,0)[``T'T'`T';``\sigma`\mu']
  410. \putmorphism(700,700)(0,-1)[``\sigma TT']{700}1m
  411. \putmorphism(1400,700)(0,-1)[``\sigma T']{700}1m
  412. \put(300,350){\makebox(0,0){4}}
  413. \put(1050,350){\makebox(0,0){5}}
  414. \put(1750,350){\makebox(0,0){7}}
  415. \end{picture}
  416. \end{center}
  417. |egroup
  418. which produces
  419. \begin{center}
  420. \xext=2100 \yext=2100
  421. \adjust[`\mu;`T\eta'T;`\sigma;`T'T\eta']
  422. \begin{picture}(\xext,\yext)(\xoff,\yoff)
  423. \putmorphism(0,2100)(0,-1)[``T\eta'T]{1400}1l
  424. \putmorphism(0,2100)(1,0)[TT`T`\mu]{700}1a
  425. \putmorphism(0,2100)(1,-1)[`TTT'`TT\eta']{700}1l
  426. \putmorphism(700,2100)(1,-1)[`TT'`T\eta]{700}1r
  427. \put(700,1750){\makebox(0,0){1}}
  428. \putmorphism(700,1420)(1,0)[\phantom{TTT'}`\phantom{TT'}`\mu
  429.   T']{700}1a
  430. \putmorphism(700,1380)(1,0)[\phantom{TTT'}`%
  431.   \phantom{TT'}`T\sigma]{700}1b
  432. \setsqparms[0`1`1`1;700`700]
  433. \putsquare(700,700)[TTT'`TT'`TT'TT'`TT'T';`T\eta'TT'``]
  434. \putmorphism(700,700)(1,0)[\phantom{TT'TT'}`%
  435.   \phantom{TT'T'}`TT'\sigma]{700}1a
  436. \put(300,1400){\makebox(0,0){2}}
  437. \put(950,1050){\makebox(0,0){3}}
  438. \settriparms[0`1`0;700]
  439. \putbtriangle(1400,700)[``TT';T\eta'T'`id`]
  440. \putmorphism(1400,700)(1,0)[\phantom{TT'T'}`%
  441.   \phantom{TT'}`T\mu']{700}1a
  442. \put(1600,1050){\makebox(0,0){6}}
  443. \setsqparms[1`1`0`1;700`700]
  444. \putsquare(0,0)[TT'T`\phantom{TT'TT'}`T'T`T'TT';%
  445.   TT'T\eta'`\sigma T``T'T\eta']
  446. \putmorphism(700,0)(1,0)[\phantom{T'TT'}`%
  447.   \phantom{T'T'}`T'\sigma]{700}1b
  448. \setsqparms[0`0`1`1;700`700]
  449. \putsquare(1400,0)[``T'T'`T';``\sigma`\mu']
  450. \putmorphism(700,700)(0,-1)[``\sigma TT']{700}1m
  451. \putmorphism(1400,700)(0,-1)[``\sigma T']{700}1m
  452. \put(300,350){\makebox(0,0){4}}
  453. \put(1050,350){\makebox(0,0){5}}
  454. \put(1750,350){\makebox(0,0){7}}
  455. \end{picture}
  456. \end{center}
  457.  
  458. Here is a page of samples of the results from the various
  459. {\tt\\putshapes}.  The code
  460. {\verbatim
  461. \begin{center}
  462. \xext=3000 \yext=3500
  463. \begin{picture}(\xext,\yext)(\xoff,\yoff)
  464. \resetparms
  465. \putsquare(0,0)[A`B`C`D;f`g`h`k]
  466. \putbtriangle(0,1500)[A`B`C;f`g`h]
  467. \putdtriangle(2200,1500)[A`B`C;f`g`h]
  468. \putptriangle(0,3000)[A`B`C;f`g`h]
  469. \putqtriangle(1000,500)[A`B`C;f`g`h]
  470. \putCtriangle(1500,750)[A`B`C;f`g`h]
  471. \putDtriangle(700,1000)[A`B`C;f`g`h]
  472. \putAtriangle(2000,2200)[A`B`C;f`g`h]
  473. \putAtrianglepair(0,2500)[A`B`C`D;f`g`h`k`l]
  474. \putVtriangle(2000,3000)[A`B`C;f`g`h]
  475. \putVtrianglepair(1000,2500)[A`B`C`D;f`g`h`k`l]
  476. \end{picture}
  477. \end{center}
  478. |egroup
  479. produces the diagram:
  480. \begin{center}
  481. \xext=3000 \yext=3500
  482. \begin{picture}(\xext,\yext)(\xoff,\yoff)
  483. \resetparms
  484. \putsquare(0,0)[A`B`C`D;f`g`h`k]
  485. \putbtriangle(0,1500)[A`B`C;f`g`h]
  486. \putdtriangle(2200,1500)[A`B`C;f`g`h]
  487. \putptriangle(0,3000)[A`B`C;f`g`h]
  488. \putqtriangle(1000,500)[A`B`C;f`g`h]
  489. \putCtriangle(1500,750)[A`B`C;f`g`h]
  490. \putDtriangle(700,1000)[A`B`C;f`g`h]
  491. \putAtriangle(2000,2200)[A`B`C;f`g`h]
  492. \putAtrianglepair(0,2500)[A`B`C`D;f`g`h`k`l]
  493. \putVtriangle(2000,3000)[A`B`C;f`g`h]
  494. \putVtrianglepair(1000,2500)[A`B`C`D;f`g`h`k`l]
  495. \end{picture}
  496. \end{center}
  497.  
  498.  
  499. Added material:
  500.  
  501. The catdoc file is out-of-date in two ways.  Most important is that all
  502. the basic shapes (square and triangles) now accept optional arguments.
  503. For example, the code
  504. {\verbatim
  505. \resetparms\square[A`B`C`D;f`g`h`k]
  506. |egroup
  507. is equivalent to simply
  508. {\verbatim
  509. |egroup
  510. \square[A`B`C`D;f`g`h`k]
  511. The code
  512. {\verbatim
  513. \settriparms[1`-1`2;750]\ptriangle[A`B`C;f`g`h]
  514. |egroup
  515. is equivalent to
  516. {\verbatim
  517. \ptriangle<1`-1`2;750>[A`B`C;f`g`h]
  518. |egroup
  519. and the code
  520. {\verbatim
  521. \settripairparms[1`-1`0`2`-3;1000]
  522. \putAtrianglepair(500,750)[A`B`C`D;f`g`h`k`l]
  523. |egroup
  524. is equivalent to
  525. {\verbatim
  526. \putAtrianglepair<1`-1`0`2`-3;1000>(500,750)[A`B`C`D;f`g`h`k`l]
  527. |egroup
  528. Note that both the old and new syntax work.
  529.  
  530. The second new things are various shapes that I have found useful enough
  531. to add over the last few months.  For example, I have both vertical and
  532. horizontal coequalizers.  Had I had the need, I would have added
  533. equalizers, and no doubt will at some future date.  Or maybe you will
  534. and can send it to me.  These can all be found by reading the source
  535. file, where they are sort of documented.
  536. \end{document}
  537.